﻿#define _CRT_SECURE_NO_WARNINGS 1
#include "snake.h"
void SETPOS(short X, short Y) {//设置光标位置
	COORD pos = { X,Y };
	HANDLE houtput = NULL;
	houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(houtput, pos);
}

void Hidecursor() {//隐藏光标函数
	HANDLE houtput = NULL;
	houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(houtput, &CursorInfo);
	CursorInfo.bVisible = false;
}

void InitSnake(psnake ps) {//初始化蛇身 
	PSnakeNode cur = NULL;
	int i = 0;
	for (i = 0; i < 5; i++) {
		cur = (PSnakeNode)malloc(sizeof(SnakeNode));
		assert(cur);
		cur->next = NULL;
		cur->x = POS_X + i * 2;
		cur->y = POS_Y;
		if (ps->psnake_node == NULL) {
			ps->psnake_node = cur;
		}
		else {
			cur->next = ps->psnake_node;
			ps->psnake_node = cur;
		}
	}
	cur = ps->psnake_node;
	while (cur) {
		SETPOS(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}
	ps->Sleeptime = 200;
	ps->Score = 0;
	ps->_Dir = RIGHT;
	ps->_Status = OK;
	ps->foodweight = 10;
	SETPOS(40, 27);
}

void CreateFood(psnake ps) {
	int a, b;
again:
	do {
		a = rand() % 53 + 2;
		b = rand() % 25 + 1;
	} while (a % 2 != 0);
	PSnakeNode cur = ps->psnake_node;
	while (cur) {
		if (cur->x == a && cur->y == b)
			goto again;
		cur = cur->next;
	}

	PSnakeNode Food = (PSnakeNode)malloc(sizeof(SnakeNode));
	assert(Food);
	Food->next = NULL;
	Food->x = a;
	Food->y = b;
	SETPOS(a, b);
	wprintf(L"%lc", FOOD);
	ps->Food = Food;
	SETPOS(40, 27);
	system("pause");
}
void CreateMap() {//创建地图
	SETPOS(0, 0);
	int i = 0;
	for (i = 0; i < 58; i = i + 2) {//上
		wprintf(L"%lc", WALL);
	}
	SETPOS(0, 26);
	for (i = 0; i < 58; i = i + 2) {//下
		wprintf(L"%lc", WALL);
	}
	for (i = 1; i < 26; i++) {//左
		SETPOS(0, i);
		wprintf(L"%lc", WALL);
	}

	for (i = 1; i < 26; i++) {//右
		SETPOS(56, i);
		wprintf(L"%lc", WALL);
	}
}
void Helpinfo() {
	SetPos(64, 15);
	printf("不能穿墙，不能咬到⾃⼰\n");
	SetPos(64, 16);
	printf("用↑.↓.←.→分别控制蛇的移动.");
	SetPos(64, 17);
	printf("F3 为加速，F4 为减速\n");
	SetPos(64, 18);
	printf("ESC ：退出游戏.space：暂停游戏.");
}
void WelcomeToGame() {//欢迎进入游戏
	Hidecursor();
	SETPOS(40, 15);
	printf("欢迎来到贪吃蛇游戏!\n");
	SETPOS(40, 25);
	system("pause");
	system("cls");
	SETPOS(25, 12);
	printf("用 ↑ ↓ ← → 分别控制蛇的移动， F3为加速，F4为减速\n");
	SETPOS(25, 13);
	printf("加速能获得更高速度\n");
	SETPOS(40, 25);
	system("pause");
	system("cls");
}

void GameRun(psnake ps) {
	Helpinfo();
	do {
		SETPOS(64, 10);
		printf("得分：%d\n", ps->Score);
		printf("每个食物得分：%d\n", ps->foodweight);
		if (KEY_PRESS(VK_UP) && ps->_Dir != DOWN) {
			ps->_Dir = UP;
		}
		else if (KEY_PRESS(VK_DOWN) && ps->_Dir != UP) {
			ps->_Dir = DOWN;
		}
		else if (KEY_PRESS(VK_LEFT) && ps->_Dir != RIGHT) {
			ps->_Dir = LEFT;
		}
		else if (KEY_PRESS(VK_RIGHT) && ps->_Dir != LEFT) {
			ps->_Dir = RIGHT;
		}
		else if (KEY_PRESS(VK_SPACE)) {
			pause();
		}
		else if (KEY_PRESS(VK_F3)) {
			if (ps->Sleeptime >= 50) {
				ps->Sleeptime = ps->Sleeptime - 30;
				ps->foodweight = ps->foodweight + 2;
			}
		}
		else if (KEY_PRESS(VK_F4)) {
			if (ps->Sleeptime < 350) {
				ps->Sleeptime = ps->Sleeptime + 30;
				ps->foodweight = ps->foodweight - 2;
			}
			if (ps->foodweight == 350) {
				ps->foodweight = 1;
			}
		}
		SnakeMove(ps);
		sleep(ps->Sleeptime);
	} while (ps->_Status == OK);
}

void test() {
	snake SNAKE = { 0 };
	WelcomeToGame();
	CreateMap();
	InitSnake(&SNAKE);
	CreateFood(&SNAKE);


}
void SnakeMove(psnake ps) {
	PSnakeNode NextPoint = (PSnakeNode)malloc(sizeof(SnakeNode));
	assert(NextPoint);
	switch (ps->_Dir) {
	case UP:
		NextPoint->x = ps->psnake_node->x;
		NextPoint->y = ps->psnake_node->y + 1;
		break;
	case LEFT:
		NextPoint->x = ps->psnake_node->x - 2;
		NextPoint->y = ps->psnake_node->y;
		break;
	case DOWN:
		NextPoint->x = ps->psnake_node->x;
		NextPoint->y = ps->psnake_node->y - 1;
	case RIGHT:
		NextPoint->x = ps->psnake_node->x + 2;
		NextPoint->y = ps->psnake_node->y;
		break;
	}
	if (NextisFood(ps, NextPoint)) {
		EatFood(ps, NextPoint);
	}
	else {
		NoFood(ps, NextPoint);
	}
	/*KillByself(ps, NextPoint);
	KillByWall(ps, NextPoint);*/

}
int NextisFood(psnake ps, PSnakeNode Next) {
	return  ((ps->Food->x == Next->x) && (ps->Food->y == Next->y));
}

void pause() {
	while (1) {
		sleep(300);
		if (KEY_PRESS(VK_SPACE))
			break;
	}
}

void EatFood(psnake ps, PSnakeNode Next) {
	Next->next = ps->psnake_node;
	ps->psnake_node = Next;
	PSnakeNode cur = ps->psnake_node;
	while (cur != NULL) {
		SETPOS(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}
	free(ps->Food);
	ps->Score = ps->Score + ps->foodweight;
	CreatFood(ps);
}

void NoFood(psnake ps, PSnakeNode Next) {
	Next->next = ps->psnake_node;
	ps->psnake_node = Next;
	PSnakeNode cur = ps->psnake_node;
	while (cur->next->next) {
		SETPOS(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}

	SETPOS(cur->x, cur->y);
	printf("  ");

}